2012-09-23 3 views
1

파일을 스캔하고 (g) awk 토큰을 강조 표시하는 프로그램을 작성 중입니다. Flex는 (g) awk에 대한 렉서 스캐너를 생성하는 데 사용됩니다.FLEX - 정규 표현식 - AWK의 일치하는 설명

문제점 : Flex의 정규 표현식 작성에 익숙하지 않습니다. 지금은 전체 주석 일치를위한 정규식을 생성하는 방법을 알 수 없습니다. 스캔 할 .awk 프로그램 샘플을 참조하십시오.

#!/usr/bin/awk -f 
############################################################################### 
# 
# @(#) solve.awk - sudoku solver in awk using efficient backtracking algorithm 
# @(#) $Id: solve.awk,v 1.16 2008/03/24 04:04:44 bduncan Exp bduncan $ 
# @(#) Copyright (C) 2005-2008, Bill Duncan, <[email protected]> 
# 
# License: 
# This program is free software: you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation, either version 3 of the License, or 
# (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program. If not, see http://www.gnu.org/licenses/. 
# 
# Description: 
# - uses simple recursive backtracking algorithm with up-front and 
# ongoing elimination of invalid tries by tracking for each row, 
# column and region.. 
# 
# Notes: 
# - precalc of regmap didn't seem to make a difference 
# - removed unmark() function and added a parameter to mark() 
# 
# Variables: 
# regmap[r,c] ; pre-compiled, which region sector is r,c 
# master[r,c] ; master matrix 
# C[col, elem] ; true if elem in Column 
# R[row, elem] ; true if elem in Row 
# Q[reg, elem] ; true if elem in Region (Quadrant) 
# 
############################################################################### 
BEGIN { 
SUBSEP = "," # so we can dump and it looks nice 
ORDER = 9 
DEBUG = 0 
count = 0 
# precompile region map for faster lookup 
# for (i = 0; i < ORDER; i++) 
# for (j = 0; j < ORDER; j++) 
# regmap[i+1,j+1] = int(i/3)*3+int(j/3)+1 
} 
function dump(i,j) { 
printf "\n" 
for (i=1;i<=ORDER;i++) { 
if (!((i-1)%3)) printf "\n" 
for (j=1;j<=ORDER;j++) { 
if (!((j-1)%3)) printf " " 
printf " %1d",master[i,j] 
} 
printf "\n" 
} 
printf "\n" 
} 
function fregmap(r,c) { 
# return regmap[r,c] 
return int((r-1)/3)*3+int((c-1)/3)+1 
} 
function inuse(r,c,try) { 
# q = fregmap(r,c) 
# can we use it or is it in use? returns true if already used, not avail 
return (C[c,try] || R[r,try] || Q[fregmap(r,c),try]) 
} 
function mark(r,c,try, flag, q) { 
q = fregmap(r,c) 
Q[q,try] = flag 
R[r,try] = flag 
C[c,try] = flag 
master[r,c] = flag ? try : 0 
} 
function search(r,c, q,i,a,try) { 
# find the next empty slot from here r,c 
# if we've reached the end (no more empty) do check? 
# for each available number, recurse search 
count++ 
while (master[r,c]) { 
if (++c > ORDER) { 
c = 1 
if (++r > ORDER) { 
# then we're done filling! return goodness 
return 1 
} 
} 
} 
# for each of the available numbers for this slot 
for (try=1; try <= ORDER; try++) { 
if (! inuse(r,c,try)) { 
mark(r,c,try, 1) 
if (search(r,c)) return 1 
# else zero returned -- unwind 
mark(r,c,try, 0) # unmark 
} 
} 
return 0 
} 
############ 
# PATTERNS # 
############ 
NF == 0 { next } 
$1 ~ /^#/ { next } 
NF != ORDER { 
printf "error on line %d, NF=%d\n", FNR, NF 
exit 1 
} 
{ 
++row 
for (col=1; col <= ORDER; col++) { 
mark(row,col,$col, 1) 
} 
} 
END { 
search(1,1) 
printf "\n# Searches=%d\n", count 
dump() 
} 

현재 "^ # +"을 사용하여 주석을 일치시킵니다. 이것은 모든 "#"문자와 일치하지만 그 행의 나머지 문자와 일치하지 않습니다. "#"다음에 나오는 모든 것을 어떻게 맞추는가?

플렉스 패턴 구조는 in the Flex manual으로 검토 할 수 있습니다.

+1

아마도'^ #. * $'과 (과) 비슷할 것입니까? 나는 완전히 확신하지 못한다. – nhahtdh

답변

0

+ 개질제 '는 하나 또는 그 이전의 형태를보다'리터럴 # 인 의미하므로 이것은 단지 하나 이상의 연속 된 해시를 들면 1 열

부터 포함 된 행의 개시 부와 일치 경기 고정 (라인의 시작), 다음이 필요합니다

^#.* 

AFAICR는 .는 줄 바꿈과 일치하지 않습니다. 이것은 #으로 시작하는 행과 그 뒤에 임의의 유형의 0 개 이상의 다른 문자 (개행을 제외하고)를 의미합니다.

awk 의견이 줄의 시작 부분에 시작하는 제한되지 않습니다 잊지 마세요 : 넓은 범위 내에서

awk '{ 
     # This comment is indented by a number of spaces 
     print $1; # And this is preceded by a command 
    }' 

, 당신은 # 건너 언제든지, 그것은 주석의 시작입니다. 한계는 문자열과 정규 표현식의 몸을 제외 :

awk '{ print "# Not a comment" }' 

awk '/#.*/ { print "Line contains a # comment: ", $0; }' 

그래서, 당신은 코멘트 규칙보다 먼저 걷어차하기 위해 정규식 규칙 및 문자열 규칙이 필요합니다.

+0

답장을 보내 주셔서 감사합니다. "." 그러나 일하게 그것을 얻을 수 없었다, 나는 붙잡기 시작하고있다! –

관련 문제